home *** CD-ROM | disk | FTP | other *** search
- /* pe7pho.c */
- /*
- * P h o n e File Transfer Utility
- *
- * usage:
- * phone -i -d -v -l -b -a -p -h -c
- *
- * where i=init modem <flag>, d=debug level <number>, v=verbose <flag>,
- * l=line <device>, b=baud rate <number>, a=answer <flag>,
- * p=phone number <string>, h=hang-up request <'a' or 'o'>,
- * c=direct connect <'a' or 'o'>
- */
-
- /*
- * Modification History:
- *
- * June 85 - Init write. Dan L. Eisner, Perkin-Elmer Corp.
- *
- */
-
- #include <std.h> /* Standard IDRIS definitions */
- #include <sys.h> /* Idris system subroutines */
- /*#include "sgtty.h" /* Special TTY speed definations */
- #include "pe7tty.h" /* Special TTY speed definations */
-
- /* Symbol Definitions */
-
- #define BUFSIZE 80 /* A buffer size for I/O */
-
- #define MYTIME 10 /* Seconds after which I should be timed out */
-
- #define TRUE -1 /* Boolean constants */
- #define FALSE 0
-
- /* Global Variables */
-
- int
- iflg {0}, /* Indicates to init the modem */
- aflg {0}, /* Indicates modem mode */
- vflg {0}, /* Indicates verbose mode */
- hflg {0}, /* Indicates to hang up the phone */
- cflg {0}, /* direct connection thru a modem flag */
- timint {0}, /* This is the present time out interval */
- debug {0}; /* indicates level of debugging output (0=none) */
-
- char modem_data[BUFSIZE] {0};/* Temp buffer for modem command data */
-
- FILE ttyfd {0}; /* File descriptor of tty for I/O */
-
- struct tty
- savemode {0}, /* tty saved mode */
- ttymode {0}; /* tty raw mode */
- /*
- * m a i n
- *
- * Main routine - parse command and options, set up the
- * tty lines, and dispatch to the appropriate routine.
- */
-
- main(argc,argv)
- int argc; /* Character pointers to and count of */
- char **argv; /* command line arguments */
-
- {
- char *ttyname, /* tty name for LINE argument */
- *ph_num, /* Phone number for PHONE argument */
- result_code, /* The code the modem answered with */
- tmp[6]; /* Retry counter buffer */
- int speed; /* speed of assigned tty, */
- int dial_count; /* Number of times we have dialed the phone */
- int answer_count; /* The number of times we tried to answer phone */
- int pflg; /* A flag to set if there is a phone number */
- int pdial; /* Pulse dialing flag */
-
- /* Make sure there's a command line */
- if (argc < 2)
- Usage("phone -i -d# -v -l/dev/tty# -b<rate> -a -p<tel. no> -h -c\n");
-
- iflg = FALSE;
- aflg = FALSE;
- hflg = FALSE;
- vflg = FALSE;
- cflg = FALSE; /* Turn off all parse flags */
- ttyname = 0; /* We did not get a line assignment (pointer) */
- ph_num = NULL; /* Set the phone number pointer to a null */
- pflg = FALSE; /* ... and the flag to FALSE */
- speed = 0; /* Preset the speed to no change */
- debug = FALSE; /* Turn off the debug mode */
-
- getflags(&argc,&argv, "i,a,v,h?,c?,l*,p*,b#,d#:F",
- &iflg, &aflg, &vflg, &hflg, &cflg, &ttyname, &ph_num, &speed, &debug);
-
- /* Done parsing */
-
- if (debug > 0)
- vflg = TRUE; /* Force verbose during debug */
-
- pflg = (ph_num != 0);/* Set up a phone number flag */
- if (!aflg && !pflg && !hflg && !cflg && !iflg)
- Usage("We need to do something?");
-
- if ((aflg + pflg) > 1)
- Usage("Dial and answer the phone?");
-
- if (cflg && (aflg || pflg))
- Usage("Direct connect and dial at same time?");
-
- if (hflg != 0 && (aflg || pflg))
- Usage("Hang-up after connecting?");
-
- if (cflg == 'a' || cflg == 'A')
- aflg = TRUE; /* make it answer */
-
- if (cflg == 'o' || cflg == 'O')
- pflg = TRUE; /* force the dial routine to work */
-
- if (aflg || pflg)
- iflg = TRUE; /* force int of modem */
-
- if (ttyname == 0) /* If LINE was not specified, we */
- ttyname = "/dev/lnk0";/* operate with link tty */
-
- ttyfd = open(ttyname, UPDATE, 0);/* Open the tty line */
- if (ttyfd < 0)
- Usage("Cannot open %s.", ttyname);
-
- /* Put the proper tty into the correct mode */
- egtty(ttyfd, &savemode);/* Save the inputed mode */
- egtty(ttyfd,&ttymode); /* set for changing the setup */
-
- ttymode.t_mode |= (M_ALL|M_RAW|MR_XON);
- ttymode.t_mode &= ~(M_ECHO | M_2STOP);
- ttymode.t_min = 128;
- ttymode.t_time = 0;
- timint = 0;
-
- if (speed) /* User specified a speed? */
- {
- switch(speed) /* Get internal system code */
- {
- case 110: speed = B110; ttymode.t_mode &= M_2STOP; break;
- case 150: speed = B150; break;
- case 300: speed = B300; break;
- case 1200: speed = B1200; break;
- case 2400: speed = B2400; break;
- case 4800: speed = B4800; break;
- case 9600: speed = B9600; break;
- default: Usage("Bad line speed.");
- }
- ttymode.t_ispeed = speed;
- ttymode.t_ospeed = speed;
- }
-
- estty(ttyfd, &ttymode); /* Put asg'd tty in raw mode */
-
- if (debug)
- {
- printf("Main 1: A=%d, H=%d, D=%d, ", aflg, hflg, cflg);
- printf("L=%s, P=%s\n", ttyname, ph_num);
- printf(" Line speed to remote host is %d\n",speed);
- printf("Main 2: Bits for ttyfd %x\n",ttymode.t_mode);
- }
-
- /* All set up, now execute the command that was given. */
-
- if (iflg) /* Init the modem */
- {
- timint = MYTIME / 2;
- ttymode.t_time = timint * 10;
- estty(ttyfd, &ttymode); /* Put tty in short time mode */
- if (vflg) printmsg("Initializing the modem");
- if ((result_code = init_modem()) <= 0)
- Usage("Can not initilize the modem, return = %d\n",result_code);
- }
- if (pflg)
- {
- timint = 0;
- ttymode.t_time = 0;
- estty(ttyfd, &ttymode); /* Put tty in long time mode */
-
- /* If the first character of the phone number is a p then set
- up pulse dialing. */
- if (*ph_num == 'p' || *ph_num == 'P')
- {
- pdial = TRUE;
- ph_num++;
- }
- else
- pdial = FALSE; /* Set pulse dialing to FALSE */
- dial_count = 0;
- if (vflg) printmsg("Dialing %s", ph_num);
- do
- {
- if (dial_count++ >= 5)
- Usage("Dial count expired");
- modem_write(pdial ? "ATPD" : "ATTD", FALSE);
- if (!cflg)
- modem_write(ph_num,FALSE);
- modem_write("\r",FALSE);
- if(vflg)
- write(STDERR, &tmp, decode(&tmp, 3, "%2i\r", dial_count));
- }
- while ((result_code = get_result()) == '3'); /* keep dialing */
-
- if (result_code != '1' && result_code != '5')
- {
- init_modem();
- Usage(" \007ERROR, BAD RESULT CODE: 0x%x\r",result_code);
- }
-
- if (vflg)
- printmsg("Connect at %s\n",
- result_code == '5' ? "1200 Baud" : "300 Baud");
- sleep(2); /* Wait for other side to be ready */
- timint = MYTIME;
- ttymode.t_time = timint * 10; /* Reset time out */
- estty(ttyfd, &ttymode);
-
- } /* End of pflg */
- if (aflg)
- {
- answer_count = 0;
- if (!cflg) /* Direct mode is off? */
- {
- timint = 30; /* set the time to 30 sec. */
- ttymode.t_time = 50;/* Make the time out as big as I can */
- estty(ttyfd, &ttymode);
- if (vflg) printmsg("Waiting for ring");
- do
- {
- if (answer_count++ >= 10)
- Usage("Answer count expired.");
- if(vflg)
- write(STDERR, &tmp, decode(&tmp, 3, "%2i\r",
- answer_count));
- }
- /* wait for phone to ring (but count tries) */
- while ((result_code = get_result()) != '2');
- modem_write("ATS2=28A\r",FALSE); /* Answer the phone */
- result_code = get_result();
- }
- else /* !cflg */
- {
- timint = 0;
- ttymode.t_time = 0; /* set time out */
- estty(ttyfd, &ttymode);
- if (vflg) printmsg("Waiting for connection");
- do
- {
- if (answer_count++ >= 5)
- Usage("Answer counter expired.");
- modem_write("ATS2=28A\r",FALSE); /* Answer the phone */
- if(vflg)
- write(STDERR, &tmp, decode(&tmp, 3, "%2i\r",
- answer_count));
- }
- while ((result_code = get_result()) == '3');
-
- } /* end of else !cflg */
- if (result_code != '1' && result_code != '5')
- Usage("Modem failed to answer correctly.");
- if (vflg)
- printmsg("Answered at %s\n",
- result_code == '5' ? "1200 Baud" : "300 Baud");
- timint = MYTIME;
- ttymode.t_time = timint * 10; /* Reset time out */
- estty(ttyfd, &ttymode); /* Put tty in time out mode */
- } /* end of aflg */
- if (hflg)
- {
- timint = MYTIME / 5;
- ttymode.t_time = timint * 10; /* restore time out count */
- estty(ttyfd, &ttymode);
- if(vflg) printmsg("Hanging up");
- hang_modem(); /* Hang up the phone */
- } /* end of else !hflg */
-
- estty(ttyfd, &savemode);
- exit(YES);
- }
-
- /*
- * p r i n t m s g
- *
- * printmsg - like printf with "Phone: " preappended
- */
- printmsg(fmt, a1, a2, a3, a4, a5)
- TEXT *fmt;
- {
- char cp[BUFSIZE];
- cpystr(&cp, "Phone: ", fmt, "\n", NULL);
- printf(&cp, a1, a2, a3, a4, a5);
- }
-
- /*
- * U s a g e
- *
- * Print formatted message and the exit with a status of NO
- */
- Usage(message, a1, a2, a3, a4, a5)
- char *message;
- {
- char cp[BUFSIZE];
-
- cpystr(&cp, "Phone usage: ", message, "\n", NULL);
- printf(&cp, a1, a2, a3, a4, a5);
- if (ttyfd > 0)
- estty(ttyfd, &savemode); /* restore the tty */
- exit(NO);
- }
-
- /*
- * p r i n t f
- *
- * Print formatted output. Convert from UNIX to IDRIS
- */
- printf(msg, a1, a2, a3, a4, a5)
- char *msg;
- {
- char t,
- *cpp,
- cp[BUFSIZE]; /* Line pointer for the reformatted string */
-
- cpp = cp; /* Init the buffer pointer */
-
- while ((t = *cpp++ = *msg++) != NULL)
- if (t == '%')
- switch(t = *msg)
- {
- case 'd': *cpp++ = 'i';
- t = *msg++; /* Scrap character */
- break;
- case 'c': *cpp++ = 'a';
- *cpp++ = 'c';
- t = *msg++; /* Scrap character */
- break;
- case 'x': *cpp++ = 'h';
- *cpp++ = 'i';
- t = *msg++; /* Scrap character */
- break;
- case 's': *cpp++ = 'p';
- t = *msg++; /* Scrap character */
- break;
- case '\0': break;
- default: *cpp++ = *msg++;
- }
- putfmt(&cp, a1, a2, a3, a4, a5);
- }
-
- /*
- * i n i t _ m o d e m
- *
- * Init the modem. first try to reset then if not successful then try to
- * escape the modem, and reset.
- * The routine returns a result of '0' to '5' or a negative number for timeout
- */
- char init_modem()
- {
- int tries;
- char tmp;
-
- if (debug) printf("Init_modem 1:\n");
-
- for (tries = 1; tries <= 4; tries++)
- {
- sleep(1); /* Wait for a bit */
- if (tries >= 2)
- {
- modem_write("\34\34\34",FALSE);
- if ((tmp = get_result()) != '0')
- {
- modem_write("\35\35\35",FALSE);
- if ((tmp = get_result()) != '0')
- {
- modem_write("+++",FALSE);
- tmp = get_result();
- }
- }
- }
- modem_write("\rATZ\r", FALSE);
- if ((tmp = get_result()) == '0') break;
- if (debug) printf("Init_modem 2: tries = %d\n",tries);
- }
- if (tries > 4) return(tmp);
-
- sleep(2); /* wait for a while while the modem resets */
- modem_write("AT E0 F1 Q0 V1 X1 S0=0 S5=255 S2=29 \r",TRUE);
- if (debug) printf("Init_modem exit\n");
- return(get_result());
- }
-
- /*
- * h a n g _ m o d e m
- *
- * Hang up the modem. First escape to the command mode, then hang up the
- * phone.
- * The routine returns a result of '0' or a negative number for timeout
- */
- char hang_modem()
- {
- int tries;
- char tmp;
-
- if (debug) printf("Hang_modem 1:\n");
-
- for (tries = 1; tries <= 4; tries++)
- {
- sleep(2); /* Wait for a bit each time */
- modem_write((hflg == 'a' || hflg == 'A') ?
- "\34\34\34" : "\35\35\35", FALSE);
- if ((tmp = get_result()) != '0')
- {
- modem_write("\34\34\34",FALSE);
- if ((tmp = get_result()) != '0')
- {
- modem_write("\35\35\35",FALSE);
- if ((tmp = get_result()) != '0')
- {
- modem_write("+++",FALSE);
- tmp = get_result();
- }
- }
- }
- modem_write("ATH0\r", FALSE);
- if ((tmp = get_result()) == '0') break;
- if (debug) printf("Hang_modem 2: tries = %d\n",tries);
- }
- if (debug) printf("Hang_modem exit\n");
- return(tmp);
- }
- /*
- * g e t _ r e s u l t
- *
- * This routine finds out the result code from the modem.
- */
- char get_result()
- {
- int tmpx; /* The status and goes here */
- char result;
- result = 0; /* Reset the result flag */
- while (result == 0) /* do till something comes in that we recognize */
- {
- if ((tmpx = modem_read(&modem_data)) <= 0)
- result = -1;
- else if (modem_data[substr(&modem_data, "OK")])
- result = '0';
- else if (modem_data[substr(&modem_data, "CONNECT 1200")])
- result = '5';
- else if (modem_data[substr(&modem_data, "RING")])
- result = '2';
- else if (modem_data[substr(&modem_data, "NO CARRIER")])
- result = '3';
- else if (modem_data[substr(&modem_data, "ERROR")])
- result = '4';
- else if (modem_data[substr(&modem_data, "CONNECT")])
- result = '1';
- if (debug)
- printf("Get_result 1: %c, %d, \"%s\"\n",result,tmpx,modem_data);
- } /* End of while loop */
- if (debug)
- printf("Get_result 2: %c, %d, \"%s\"\n",result,tmpx,modem_data);
- return(result);
- }
- /*
- * m o d e m _ w r i t e
- *
- * send a string to the modem. If eat is TRUE, eat a single echo per xmitted
- * character. Does not account for echoed \n's after \r's. Current version
- * turns off command echo anyway, so no difference.
- */
-
- modem_write(s, eat)
- char *s;
- int eat;
- {
- char t;
- int tmpx;
- tmpx = 1;
- while (*s)
- {
- write(ttyfd, s++, 1);
- if (eat)
- if ((tmpx = ioread(&t)) <= 0) break;
- }
- return(tmpx);
- }
- /*
- * m o d e m _ r e a d
- *
- * Modem read routine. This routine reads the returned control data from
- * The modem.
- */
- modem_read(t)
- char *t;
- {
- char chr;
- BYTES point;
- point = t; /* Set pointer to start of the string */
- while (TRUE)
- {
- if (ioread(t) <= 0) break; /* If an error or eof then exit */
- if (*t == '\n') /* What was the last character? */
- {
- *t++ = '\134'; *t++ = 'n'; /* Make the return into a \n */
- break; /* If it was an EOL then exit */
- }
- if ((chr = *t) < ' ')
- {
- *t++ = '\134'; *t = chr + '@'; /* Make control to alpha */
- }
- t++; /* Bump the pointer */
- }
- *t = NULL; /* Make sure the string ends with a null */
- return(t - point); /* Return a character counter */
- }
-
- /*
- * i o r e a d
- *
- * Read a character from the i/o channel
- */
- ioread(t)
- char *t;
- {
- ULONG time_end,
- time();
- int result;
- if (timint > 0)
- {
- time_end = time() + timint;
- while (time_end >= time())
- if ((result = read(ttyfd, t, 1)) > 0) break;
- }
- else
- result = read(ttyfd, t, 1);
- return(result);
- }
- /* pe7pho.c End-of-file */
-